#include "httpmanager.h"
#include <QHttpMultiPart>
#include <QHttpPart>
#include <QFile>
#include <QUrlQuery>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDebug>


HttpManager::HttpManager(QObject *parent) : QObject(parent)
{
    m_manager = new QNetworkAccessManager(this);
    connect(m_manager, &QNetworkAccessManager::finished,
            this, &HttpManager::onReplyFinished);
}

HttpManager::~HttpManager()
{
    // 自动释放所有未完成的请求
    for (auto reply : m_callbacks.keys()) {
        reply->abort();
        reply->deleteLater();
    }
}

HttpManager *HttpManager::instance()
{
    static HttpManager instance;
    return &instance;
}

void HttpManager::postWithFile(const QString &url, const QMap<QString, QString> &formData, const QString &fileKey, const QString &filePath, HttpSuccess successCb, HttpError errorCb)
{
    // 校验文件是否存在、
    if (!QFile::exists(filePath)) {
        errorCb(-1, "文件不存在: " + filePath);
        return;
    }

    // 构建multipart请求体
    auto* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    // 添加文本字段
    for (auto it = formData.begin(); it != formData.end(); ++it) {
        QHttpPart part;
        part.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QString("form-data; name=\"%1\"").arg(it.key()));
        part.setBody(it.value().toUtf8());
        multiPart->append(part);
    }

    // 添加文件字段
    QHttpPart filePart;
    QFile* file = new QFile(filePath);
    if (!file->open(QIODevice::ReadOnly)) {
        errorCb(-2, "文件打开失败: " + filePath);
        delete file;
        delete multiPart;
        return;
    }
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QString("form-data; name=\"%1\"; filename=\"%2\"")
                       .arg(fileKey).arg(file->fileName()));
    filePart.setBodyDevice(file);
    file->setParent(multiPart);  // 让multiPart管理文件生命周期
    multiPart->append(filePart);

    // 发送请求并关联回调
    QNetworkRequest request(url);
    QNetworkReply* reply = m_manager->post(request, multiPart);
    multiPart->setParent(reply);  // 让reply管理multiPart生命周期
    m_callbacks[reply] = {successCb, errorCb};
}

void HttpManager::postForm(const QString &url, const QMap<QString, QString> &formData, HttpSuccess successCb, HttpError errorCb)
{
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");

    QUrlQuery query;
    for (auto it = formData.begin(); it != formData.end(); ++it) {
        query.addQueryItem(it.key(), it.value());
    }

    QNetworkReply* reply = m_manager->post(request, query.toString().toUtf8());
    m_callbacks[reply] = {successCb, errorCb};
}

void HttpManager::get(const QString &url, const QMap<QString, QString> &params, HttpSuccess successCb, HttpError errorCb)
{
    QUrl reqUrl(url);
    QUrlQuery query;
    for (auto it = params.begin(); it != params.end(); ++it) {
        query.addQueryItem(it.key(), it.value());
    }
    reqUrl.setQuery(query);

    QNetworkRequest request(reqUrl);
    QNetworkReply* reply = m_manager->get(request);
    m_callbacks[reply] = {successCb, errorCb};
}

void HttpManager::onReplyFinished(QNetworkReply *reply)
{
    // 获取并移除回调（确保只处理一次）
    if (!m_callbacks.contains(reply)) {
        reply->deleteLater();
        return;
    }
    auto [successCb, errorCb] = m_callbacks.take(reply);

            // 处理网络错误
            if (reply->error() != QNetworkReply::NoError) {
        errorCb(reply->error(), reply->errorString());
        reply->deleteLater();
        return;
    }

    // 解析JSON响应（统一处理格式错误）
    QByteArray data = reply->readAll();
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data);
    if (!jsonDoc.isObject()) {
        errorCb(-3, "响应格式错误，非JSON对象: " + data);
        reply->deleteLater();
        return;
    }

    // 调用业务成功回调
    successCb(jsonDoc.object());
    reply->deleteLater();
}

void HttpManager::postJson(const QString& url, const QJsonObject& jsonData,
                           HttpSuccess successCb, HttpError errorCb) {
    QNetworkRequest request(url);
    // 设置JSON格式的Content-Type
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    // 将QJsonObject转换为JSON字节数组
    QByteArray jsonDataBytes = QJsonDocument(jsonData).toJson();

    QNetworkReply* reply = m_manager->post(request, jsonDataBytes);
    m_callbacks[reply] = {successCb, errorCb};
}
